package cn.edu.nenu.contract;
import java.util.List;

import javax.ejb.Remote;

import cn.edu.nenu.contract.dto.AssignmentDTO;
import cn.edu.nenu.contract.dto.EmployeeDTO;
import cn.edu.nenu.contract.dto.ProjectDTO;
import cn.edu.nenu.contract.dto.SimpleTaskDTO;
import cn.edu.nenu.contract.dto.TaskSolverDTO;
import cn.edu.nenu.contract.dto.TaskStatusDTO;
import cn.edu.nenu.contract.dto.WorkTaskDTO;
import cn.edu.nenu.contract.eto.AssignmentNotPersistedException;
import cn.edu.nenu.contract.eto.TaskNameIllegalException;
import cn.edu.nenu.contract.eto.TaskNotPersistedException;
import cn.edu.nenu.contract.eto.TaskSolverUnknownException;
import cn.edu.nenu.contract.eto.TaskUnknownException;
import cn.edu.nenu.contract.eto.TooFewHoursException;



@Remote
public interface ITaContract {
	
	//purely for testing. Returns String "hello " + name + "!", or something like it.
	String sayHello(String name);
	
	/**
	 *  This method return a list of tasks in project.<br>
	 *  If parameter is null a list of Task Owners level 1 tasks (projects) are returned.<br><br>
	 *  Level 1 tasks are defined as being the projects in the root of
	 *  the task tree.<br>
	 *  Preconditions: a user has been identified and authenticated as Task Owner.<br/>
	 *  Postconditions:
	 *  @param projectId - -1 if Task Owners level 1 tasks (projects) are returned
	 *  @return List of SimpleTaskDTO - all tasks in project - null if none
	 *  @throws Exception
	 */		
	List<SimpleTaskDTO> getProjectTasks(int projectId) throws TaskUnknownException, Exception;
	
	
	/**
	 *  This method returns a list of unallocated tasks in project.<br/>
	 *  Unallocated tasks are defined as not fully allocated tasks. In other words 
	 *  tasks where the sum of assigned work hours 
	 *  for the task, is less than the required amount of work hours for the task.<br/>
	 *  The required amount of work hours for a project is equal to the sum of required 
	 *  work hours for all work tasks in the project and all its sub projects.<br/><br/>
	 *  Preconditions: A user has been identified and authenticated as Task Owner.<br/>
	 *  Postconditions:
	 *  @param projectId - if null Task Owners level 1 tasks (projects) are returned
	 *  @return List of SimpleTaskDTO - all unallocated tasks in project - null if none
	 *  @throws Exception
	 */		
	List<SimpleTaskDTO> getUnallocatedTasks(int projectId) throws TaskUnknownException, Exception;

	
	/**
	 *  Creates and persists a work task.<br>
	 *  Ensure work task name is unique for work tasks in the level 1 
	 *  project where work task belongs, before persisting this method .<br/><br/>
	 *  Preconditions: Data syntax in WorkTaskDTO is correct.
	 *  A user has been identified and authenticated as Task Owner.<br/>
	 *  Postconditions:
	 *  @param workTaskDTO - the workTask to persist.
	 *  @throws TaskNotPersistedException - thrown when creation or persisting fails.
	 *  @throws TaskNameIllegalException - thrown when name 
	 *  in WorkTaskDTO is not unique in the level 1 project.
	 *  @throws Exception
	 */		
	void submitWorkTask(WorkTaskDTO workTaskDTO) throws TaskNotPersistedException, TaskNameIllegalException, Exception;
	
	
	/**
	 *  Creates and persists a project.<br/><br/>
	 *  This method must ensure that the project name is unique for Task Owner's projects.<br/><br/>
	 *  Preconditions: Data syntax in ProjectDTO is correct.
	 *  A user has been identified and authenticated as Task Owner.<br/>
	 *  Postconditions: 
	 *  @param projectDTO - project to persist
	 *  @throws TaskNotPersistedException - thrown when creation or persisting fails
	 *  @throws TaskNameIllegalException - thrown when name in ProjectDTO is already used by Task Owner.
	 *  @throws Exception
	 */		
	void submitProject(ProjectDTO projectDTO) throws TaskNotPersistedException, TaskNameIllegalException, Exception;
	
	
	/**
	 *  Returns all Task Solvers assigned to the task. If task is a project all Task Solvers
	 *  assigned to work tasks (at any level) in project are returned.<br/>If task is a work task
	 *  only Task Solvers assigned to the specific task are returned.
	 *  Preconditions:<br/>
	 *  Postconditions:
	 *  @param taskId : int - The method is returning a list of Task Solvers assigned to this task.
	 *  @return List of TaskSolverDTO - null if none
	 *  @throws TaskUnknownException - thrown when taskId is not recognized.
	 *  @throws Exception
	 */		
	List<TaskSolverDTO> getAssignedTaskSolvers(int taskId) throws TaskUnknownException, Exception;


	
	/**
	 *  Returns a list of Task Solvers still having used less than 
	 *  their maximum allowed work hours next week.<br><br>
	 *  Preconditions:<br/>
	 *  Postconditions:
	 *  @return List of TaskSolverDTO - null if none
	 *  @throws Exception
	 */		
	List<TaskSolverDTO>  getAvailableTaskSolvers() throws Exception;

	
	/**
	 *  Request a Task Solver to make assignment for a specific task.
	 *  This results in Task Solver "scoring" 1.25 times work hour per actual work hour used on the task.<br>
	 *  So, if MR. Young, a Task Solver invited to work on ProgrammingTask1, works 4 hours on ProgrammingTask1 
	 *  the system will record him as having worked 5 hours.<br>
	 *  Additionally this method is responsible for sending an email to the Task Solver in question.
	 *  Preconditions:<br/>
	 *  Postconditions:
	 *  @param employeeId : int - Task solver to invite
	 *  @param taskId : int - Work task to invite taskSolver for
	 *  @return List of TaskSolverDTO - null if none
	 *  @throws TaskSolverUnknownException - thrown when Task Solver is not recognized.
	 *  @throws TaskUnknownException - thrown when work task-parameter is not recognized
	 *  @throws Exception
	 */		
	void  requestTaskSolverAssignment(int employeeId, int taskId)
				throws TaskSolverUnknownException, TaskUnknownException;

	
	/**
	 *  Returns a list of work tasks which are not yet fully allocated.
	 *  Preconditions:<br/>
	 *  Postconditions:
	 *  @return List of WorkTaskDTO - null if none
	 *  @throws Exception
	 *  
	 */		
	List<WorkTaskDTO>  getAvailableWorkTasks() throws Exception;

	

	
	/**
	 *  Returns a list of Task Solvers assignments for specified week current year. 
	 *  Preconditions: User has been identified and authenticated as Task Solver.<br/>
	 *  Postconditions:
	 *  @param week : int - week number in current year
	 *  @return List of AssignmentDTO - null if none of 
	 */		
	List<AssignmentDTO> getTaskSolverAssignments(int weekNumber) throws Exception;
	
	
	/**
	 *  Creates and persists an assignment.<br><br>
	 *  Preconditions: A user has been identified and authenticated as Task Solver. 
	 *  Task Solver does not violate work hour rules by creating assignment.<br/>
	 *  Postconditions:
	 *  @param workTaskId : int - workTask to make assignment for
	 *  @param workHours : int - amount of work hours in this assignment
	 *  @throws AssignmentNotPersistedException
	 *  @throws ToFewHoursException 
	 *  @throws Exception
	 */		
	void SubmitAssignment(int workTaskId, int workHours) throws AssignmentNotPersistedException, TooFewHoursException, Exception;
	
	
	/**
	 *  Checks if user name exists and the password fits. 
	 *  Preconditions: No users are logged in.<br/>
	 *  Postconditions:
	 *  @param username : String
	 *  @param password : String
	 *  @return EmployeeDTO - null if login failed
	 *  @throws Exception
	 */
	EmployeeDTO login(String username, String password) throws Exception;
	
	
	/**
	 *  Logs out user if any are logged in.
	 *  Preconditions:
	 *  Postconditions: No users are logged in.
	 *  @throws Exception
	 */
	void logout() throws Exception;
	
	
	/**
	 *  Returns a DTO specifying the status of the Task.
	 *  Preconditions: 
	 *  Postconditions:
	 *  @param simpleTaskDTO : TaskStatusDTO
	 *  @return TaskStatusDTO  
	 *  @throws TaskUnknownException,Exception - thrown when task is not recognized
	 */
	TaskStatusDTO getTaskStatus(SimpleTaskDTO simpleTaskDTO) throws TaskUnknownException, Exception;
	
	
	/**
	 * Returns a list of DTOs representing the assignments for a given work task
	 * Preconditions:
	 * Postconditions:
	 * @param task : SimpleTaskDTO
	 * @return List<AssignementDTO>
	 * @throws TaskUnknownException,Exception
	 */
	List<AssignmentDTO> getWorkTaskAssignments(SimpleTaskDTO task) throws TaskUnknownException, Exception;
	
	
	/**
	 * Returns a list of DTOs representing the assignments for a given project
	 * Preconditions:
	 * Postconditions:
	 * @param task : SimpleTaskDTO
	 * @return List<AssignementDTO>
	 * @throws TaskUnknownException, Exception
	 */
	List<AssignmentDTO> getProjectAssignments(SimpleTaskDTO task) throws TaskUnknownException, Exception;
	/**
	 * Returns a ProjectDTO representing a project with a given id
	 * @param id
	 * @return ProjectDTO
	 * @throws TaskUnknownException, Exception
	 */
	ProjectDTO getProject(int id) throws TaskUnknownException, Exception;
	/**
	 * Returns a workTaskDTO representing a work task with a given project
	 * @param id
	 * @return WorkTaskDTO
	 * @throws TaskUnknownException, Exception
	 */
	WorkTaskDTO getWorkTask(int id) throws TaskUnknownException, Exception;
	/**
	 * Creates a new Employee. Id is set by back-end
	 * @param name
	 * @param email
	 * @param username
	 * @param password
	 * @param employeeType
	 * @throws Exception
	 */
	void createEmployee(String name, String email, String username, String password, int employeeType) throws Exception;
	

}
